package com.antdant.service;

import com.antdant.entity.Comment;
import com.antdant.entity.Reply;
import com.antdant.entity.User;
import com.antdant.repository.ReplyRepository;
import com.antdant.utils.DataUtils;
import com.antdant.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @Author Lee Yunc
 * @Date 2021/3/2 17:05
 * @Description:
 * @Version 1.0
 */
@Slf4j
@Service
public class ReplyService {

    @Resource
    private ReplyRepository replyRepository;

    @Resource
    private CommentsService commentsService;

    /**
     * 根据回复的评论id删除回复
     *
     * @param commentId
     */
    public boolean deleteReplyByToWhich(Integer commentId) {
        try {
            replyRepository.deleteByReplyToId(commentId);
            return true;
        } catch (RuntimeException e) {
            return false;
        }
    }

    /**
     * 返回回复分页数据
     *
     * @param current
     * @param size
     * @param reply
     * @return
     */
    public Page<Reply> getAllReply(Integer current, Integer size, Reply reply) {
        Sort sort = Sort.by(Sort.Direction.DESC, "supportCount");//根据获赞排列
        Pageable pageable = PageRequest.of(current - 1, size, sort);
        return replyRepository.findAll(new Specification<Reply>() {
            @Override
            public Predicate toPredicate(Root<Reply> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> list = new ArrayList<>();
                if (reply.getReplyToId() != -1) {
                    list.add(criteriaBuilder.equal(root.get("replyToId"), reply.getReplyToId()));
                }
                if (DataUtils.isNotEmptyStr(reply.getUserName())) {
                    list.add(criteriaBuilder.like(root.get("userName"), reply.getUserName()));
                }
                if (DataUtils.isNotEmptyStr(reply.getContent())) {
                    list.add(criteriaBuilder.like(root.get("content"), reply.getContent()));
                }
                return criteriaBuilder.and(list.toArray(new Predicate[list.size()]));
            }
        }, pageable);
    }

    /**
     * 根据回复id删除回复
     *
     * @param replyId
     * @return
     */
    public boolean deleteReplyById(Integer replyId) {
        try {
            Comment comment = commentsService.getCommentById(Objects.requireNonNull(replyRepository.findById(replyId).orElse(null)).getReplyToId());
            Integer replyCount = comment.getReplyCount();
            replyRepository.deleteById(replyId);
            comment.setReplyCount(replyCount - 1);
            commentsService.updateComment(comment);
            return true;
        } catch (RuntimeException e) {
            return false;
        }
    }

    /**
     * 点赞+1
     *
     * @param replyId
     * @return
     */
    public Reply addSupport(Integer replyId) {
        Reply reply = replyRepository.findById(replyId).orElse(null);
        assert reply != null;
        Integer supportCount = reply.getSupportCount() + 1;
        reply.setSupportCount(supportCount);
        return replyRepository.saveAndFlush(reply);
    }

    /**
     * 新增一条回复
     *
     * @param reply
     * @param user
     * @return
     */
    public Reply addNewReply(Reply reply, User user) {
        Reply newReply = createNewReply();
        newReply.setReplyToId(reply.getReplyToId());
        newReply.setContent(reply.getContent());
        newReply.setAvatar(user.getAvatar());
        newReply.setUserId(user.getId());
        newReply.setUserName(user.getUsername());
        newReply.setIsManager(user.getIsManager());
        commentsService.addReplyCount(reply.getReplyToId());
        return replyRepository.saveAndFlush(newReply);
    }

    /**
     * 新回复初始化
     *
     * @return
     */
    private Reply createNewReply() {
        Reply reply = new Reply();
        reply.setSupportCount(0);
        reply.setCreateTime(DateUtils.getNowTime());
        return reply;
    }

    /**
     * 授权用户为管理员，更新回复信息
     *
     * @param applyFromId
     */
    public void toBeManager(Integer applyFromId) {
        List<Reply> replies = replyRepository.findAll(new Specification<Reply>() {
            @Override
            public Predicate toPredicate(Root<Reply> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Predicate temp = criteriaBuilder.equal(root.get("userId"), applyFromId);
                return temp;
            }
        });
        for (Reply reply : replies) {
            reply.setIsManager(1);
            replyRepository.saveAndFlush(reply);
        }
    }
}
